<template>
  <div class="organization-tree">
    <el-tree
      ref="treeRef"
      :data="treeData"
      :props="treeProps"
      :default-expand-all="defaultExpandAll"
      :expand-on-click-node="false"
      :highlight-current="highlightCurrent"
      :show-checkbox="showCheckbox"
      :check-strictly="checkStrictly"
      :node-key="nodeKey"
      :default-checked-keys="defaultCheckedKeys"
      @node-click="handleNodeClick"
      @check-change="handleCheckChange"
      @check="handleCheck"
    >
      <template #default="{ node, data }">
        <div class="custom-tree-node">
          <el-icon :size="16" style="margin-right: 5px">
            <OfficeBuilding v-if="data.orgType === 1" />
            <Folder v-else-if="data.orgType === 2" />
            <UserFilled v-else />
          </el-icon>
          <span class="node-label">{{ node.label }}</span>
          <span class="node-info">
            <el-tag v-if="showMemberCount && data.memberCount > 0" size="small" type="info">
              {{ data.memberCount }}人
            </el-tag>
            <el-tag v-if="data.orgTypeName" size="small">{{ data.orgTypeName }}</el-tag>
          </span>
        </div>
      </template>
    </el-tree>
  </div>
</template>

<script setup>
import { ref, watch, onMounted } from 'vue'
import { getOrganizationTree } from '@/api/organization'
import { ElMessage } from 'element-plus'

const props = defineProps({
  // 是否显示复选框
  showCheckbox: {
    type: Boolean,
    default: false
  },
  // 是否高亮当前节点
  highlightCurrent: {
    type: Boolean,
    default: true
  },
  // 是否默认展开所有节点
  defaultExpandAll: {
    type: Boolean,
    default: true
  },
  // 在显示复选框的情况下，是否严格的遵循父子不互相关联的做法
  checkStrictly: {
    type: Boolean,
    default: false
  },
  // 默认选中的节点key数组
  defaultCheckedKeys: {
    type: Array,
    default: () => []
  },
  // 是否显示成员数量
  showMemberCount: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['node-click', 'check-change', 'check'])

const treeRef = ref(null)
const treeData = ref([])
const treeProps = {
  label: 'orgName',
  children: 'children'
}
const nodeKey = 'id'

// 加载组织树数据
const loadTreeData = async () => {
  try {
    const res = await getOrganizationTree()
    if (res.code === 200) {
      treeData.value = res.data
    }
  } catch (error) {
    console.error('加载组织树失败:', error)
    ElMessage.error('加载组织树失败')
  }
}

// 节点点击事件
const handleNodeClick = (data, node) => {
  emit('node-click', data, node)
}

// 复选框状态变化事件
const handleCheckChange = (data, checked, indeterminate) => {
  emit('check-change', data, checked, indeterminate)
}

// 复选框选中事件
const handleCheck = (data, checkedInfo) => {
  emit('check', data, checkedInfo)
}

// 获取选中的节点
const getCheckedNodes = (leafOnly = false, includeHalfChecked = false) => {
  return treeRef.value?.getCheckedNodes(leafOnly, includeHalfChecked)
}

// 获取选中的节点key
const getCheckedKeys = (leafOnly = false) => {
  return treeRef.value?.getCheckedKeys(leafOnly)
}

// 设置选中的节点
const setCheckedKeys = (keys) => {
  treeRef.value?.setCheckedKeys(keys)
}

// 设置选中的节点
const setCheckedNodes = (nodes) => {
  treeRef.value?.setCheckedNodes(nodes)
}

// 获取当前选中节点
const getCurrentNode = () => {
  return treeRef.value?.getCurrentNode()
}

// 获取当前选中节点key
const getCurrentKey = () => {
  return treeRef.value?.getCurrentKey()
}

// 设置当前选中节点
const setCurrentKey = (key) => {
  treeRef.value?.setCurrentKey(key)
}

// 刷新树数据
const refresh = () => {
  loadTreeData()
}

// 暴露方法给父组件
defineExpose({
  getCheckedNodes,
  getCheckedKeys,
  setCheckedKeys,
  setCheckedNodes,
  getCurrentNode,
  getCurrentKey,
  setCurrentKey,
  refresh
})

onMounted(() => {
  loadTreeData()
})

watch(() => props.defaultCheckedKeys, (newKeys) => {
  if (newKeys && newKeys.length > 0) {
    setCheckedKeys(newKeys)
  }
}, { immediate: true })
</script>

<style scoped>
.organization-tree {
  height: 100%;
  overflow-y: auto;
}

.custom-tree-node {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex: 1;
  padding-right: 8px;
}

.node-label {
  flex: 1;
  margin-right: 10px;
}

.node-info {
  display: flex;
  gap: 5px;
  align-items: center;
}
</style>
